﻿using System;

using Microsoft.WowAddonStudio.Lua.Parser;

namespace Microsoft.WowAddonStudio.Lua.AST
{
    /// <summary>
    /// Represents an identifier node in the AST for the Lua code file.
    /// </summary>
    public class Identifier : Node
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Identifier"/> class.
        /// </summary>
        /// <param name="location">The location of the node.</param>
        public Identifier(LexLocation location)
            : base(location)
        {
        }

		/// <summary>
		/// Gets or sets the name of the identifier.
		/// </summary>
		/// <value>The name.</value>
        public string Name { get; set; }

        /// <summary>
        /// Performs an implicit conversion from <see cref="System.String"/> to <see cref="Microsoft.WowAddonStudio.Lua.AST.Identifier"/>.
        /// </summary>
        /// <param name="identifierName">Name of the identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator Identifier(string identifierName)
        {
            if (identifierName == null)
                return null;

            return new Identifier(null)
                   {
                       Name = identifierName
                   };
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator ==(Identifier left, Identifier right)
        {
            if (Object.ReferenceEquals(left, right))
                return true;
            if (Object.ReferenceEquals(left, null) || Object.ReferenceEquals(right, null))
                return false;

            return (left.Name == right.Name);
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator !=(Identifier left, Identifier right)
        {
            return !(left == right);
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">
        /// The <paramref name="obj"/> parameter is null.
        /// </exception>
        public override bool Equals(object obj)
        {
            return (this == obj as Identifier);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </returns>
        public override string ToString()
        {
            return this.Name;
        }
    }
}
